Skip to content

fix(setup): fix the agent sandbox and give the agent more facts (6/6) - #899

Open
atornsii wants to merge 12 commits into
atorns/agent-5-opencode-handlerfrom
atorns/agent-6-run-fixes
Open

atornsii wants to merge 12 commits into
atorns/agent-5-opencode-handlerfrom
atorns/agent-6-run-fixes

Conversation

@atornsii

@atornsii atornsii commented Oct 20, 2026 •

Copy link
Copy Markdown

This fixes problems that test runs found.

Sandbox (run 8)

  • Resolving a path reads the metadata of each parent folder. The sandbox denied it, so realpath, uv, and git failed with "Operation not permitted", and the agent fell back to pip. The parents of each open folder now allow metadata reads, but not their contents.
  • ~/.local/share/uv is now writable, because uv writes there when it inspects a managed Python.
  • The sandbox now closes /private/tmp, where the agent found another program's files. Each run gets its own temporary folder there, which OpenCode gets as TMPDIR.
  • The loopback proxy no longer writes "http: proxy error" lines into the wizard's screen.

Testing

Sandbox tests now also check realpath in the project, a closed file in /private/tmp, and a writable run folder. uv python find, realpath, git status, and OpenCode work in the sandbox in the test app. New tests cover the provider key names and the facts.

Diagram

flowchart TD
  subgraph facts [Facts for the agent]
    cmds["commands.go<br/>startAgent: project, environment"]:::chg
    cmdag["cmd/setup/agent.go<br/>agentTask with project, environment<br/>--project, --environment"]:::chg
    keys["provider_keys.go<br/>ProviderKeys, dotEnvNames"]:::new
    task["agent.go<br/>Task.ProjectKey, EnvironmentKey<br/>Task.ProviderKeys"]:::chg
    prompt["prompt.go<br/>BuildFacts: project, environment<br/>key names, TMPDIR note"]:::chg
    cmds -->|agentTask| cmdag
    cmdag -->|ProviderKeys| keys
    cmdag -->|fills Task| task
    prompt -->|reads Task| task
  end
  subgraph box [Sandbox and screen]
    srv["server.go<br/>TMPDIR = box.TempDir"]:::chg
    sb["sandbox.go<br/>parentFolders<br/>RunTemp, sharedTemp<br/>.local/share/uv writable"]:::chg
    proc[["opencode serve<br/>own TMPDIR"]]:::ext
    tmp[["/private/tmp<br/>closed, except the run folder"]]:::ext
    proxy["relay_proxy.go<br/>ErrorLog: discard"]:::chg
    srv -->|sandboxCommand| sb
    srv -->|sets TMPDIR| proc
    sb -.->|profile rules| tmp
  end
  classDef new fill:#e6f0fa,stroke:#1d6fb8,stroke-width:2px,color:#19202b
  classDef chg fill:#fbf1e1,stroke:#a86a12,stroke-width:2px,color:#19202b
  classDef earlier fill:#ffffff,stroke:#7a8494,stroke-dasharray:5 4,color:#19202b
  classDef ext fill:#eceefa,stroke:#4e5a9c,stroke-width:2px,color:#19202b
Loading

Blue boxes are new files, orange boxes are changed files, dashed boxes are files from an earlier PR, and purple boxes are outside ldcli. A solid arrow goes from the caller to the code that it calls. A dashed arrow shows data that moves without a direct call.

The facts group starts in the wizard. commands.go passes the selected project and environment to agentTask, which also calls ProviderKeys to get the names of the provider keys that are set. agentTask puts these values in the Task, and BuildFacts writes them into the first message. In the sandbox group, sandboxCommand now creates a run folder in /private/tmp and closes the rest of that folder. It returns the run folder as TempDir, and server.go gives it to OpenCode as TMPDIR. The profile also allows metadata reads on parent folders, so realpath, uv, and git work. relay_proxy.go stops writing proxy errors on the wizard screen.

The two groups do not depend on each other. The facts group changes the wizard from #895 and the prompt from #897. The sandbox group changes files from #896 and #897.

Stack

This is one of six PRs for the ldcli setup agent. Review and merge them in order, after #877 (Go 1.26):

  1. OpenCode adapter
  2. Wizard agent step
  3. macOS sandbox
  4. AI SDK and relay
  5. OpenCode handler
  6. Run fixes

They replace #876 and #878.

🤖 Generated with Claude Code


Note

Overview
Enriches the setup agent’s context by passing LaunchDarkly project and environment from the wizard/agentcontrol into agent.Task, detecting model provider API key names (env + .env, names only) via new ProviderKeys, and surfacing those facts plus shared setup rules (no key hunting, use $TMPDIR) in BuildPrompt/BuildFacts.

Hardens the macOS Seatbelt sandbox: allows parent-folder metadata reads so realpath/uv/git work; makes ~/.local/share/uv writable; denies /private/tmp except a per-run temp dir passed as TMPDIR to OpenCode. Silences relay proxy error logs so they don’t corrupt the wizard UI.

Reviewed by Cursor Bugbot for commit e68aa99. Bugbot is set up for automated code reviews on this repo. Configure here.

atornsii and others added 2 commits October 19, 2026 23:43
A test run found three problems with the macOS sandbox.

Resolving a path reads the metadata of every parent folder, and the
sandbox denied it. So realpath, uv, and git failed with "Operation not
permitted", and the agent fell back to pip and edited pyproject.toml by
hand. The parents of each open folder now allow metadata reads, but not
their contents.

uv writes to ~/.local/share/uv when it inspects a managed Python, and
the sandbox opened that folder read-only. It is now writable.

The agent searched /private/tmp and found another program's files
there. The sandbox now closes /private/tmp and gives the run its own
temporary folder in it, which OpenCode gets as TMPDIR.

The loopback proxy also wrote "http: proxy error" lines into the
wizard's screen. It now discards its log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In test runs, the agent spent about 25 tool calls finding the project
and environment that setup used, and it printed the environment or
asked the user to paste an API key to learn whether one was set.

The facts message now also gives the LaunchDarkly project and
environment, and the names of the model provider keys that are set in
the environment or in the project's .env. It never gives a value. It
tells the agent not to look for keys, print the environment, or ask for
a key, and to use $TMPDIR instead of /tmp.

`ldcli setup agent` takes --project and --environment for the same
facts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@atornsii
atornsii added this pull request to stack #902 October 20, 2026 15:48
@atornsii
atornsii marked this pull request as ready for review October 20, 2026 18:40
@atornsii
atornsii requested a review from a team as a code owner October 20, 2026 18:40
@atornsii
atornsii requested review from tiffanylphan and removed request for a team October 20, 2026 18:40
devin-ai-integration[bot]

This comment was marked as resolved.

…env keys

BuildPrompt now gives the project, the environment, the provider key names, and the same rules as BuildFacts. The agent gets these facts when the AI Config cannot load.

ProviderKeys now trims the value after it removes the quotes, so a quoted blank value does not count as a set key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

atornsii and others added 5 commits October 20, 2026 11:46
If the sandbox gives no run folder and TMPDIR is not set, ldcli now sets TMPDIR to the system temporary folder. The prompt tells the agent to use $TMPDIR on every platform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… into atorns/agent-6-run-fixes

# Conflicts:
#	cmd/setup/agent_test.go
… into atorns/agent-6-run-fixes

# Conflicts:
#	internal/setup/agent/sandbox.go
… into atorns/agent-6-run-fixes

# Conflicts:
#	internal/setup/agent/sandbox.go
cursor[bot]

This comment was marked as resolved.

atornsii and others added 2 commits October 20, 2026 12:14
…y folder

parentFolders now also walks the folders between an open folder and /private/tmp. A project in a nested folder under /tmp can then use realpath, uv, and git in the sandbox.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… into atorns/agent-6-run-fixes

# Conflicts:
#	internal/setup/agent/sandbox_test.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant